Next: Obsolete Features, Previous: Common Lisp Compatibility, Up: Top [Contents][Index]
This package is meant to be used as an extension to Emacs Lisp, not as an Emacs implementation of true Common Lisp. Some of the remaining differences between Emacs Lisp and Common Lisp make it difficult to port large Common Lisp applications to Emacs. For one, some of the features in this package are not fully compliant with ANSI or Steele; see Common Lisp Compatibility. But there are also quite a few features that this package does not provide at all. Here are some major omissions that you will want to watch out for when bringing Common Lisp code into Emacs.
foo in one place and
Foo or FOO in another. Emacs Lisp
will treat these as three distinct symbols.
Some Common Lisp code is written entirely in upper case.
While Emacs is happy to let the program’s own functions
and variables use this convention, calls to Lisp builtins
like if and defun will have to be
changed to lower case.
let bindings apply only to references physically
within their bodies (or within macro expansions in their
bodies). Traditionally, Emacs Lisp uses dynamic
scoping wherein a binding to a variable is visible even
inside functions called from the body. See
Dynamic Binding in GNU Emacs Lisp Reference
Manual. Lexical binding is available since Emacs 24.1,
so be sure to set lexical-binding to
t if you need to emulate this aspect of Common
Lisp. See
Lexical Binding in GNU Emacs Lisp Reference
Manual.
Here is an example of a Common Lisp code fragment that
would fail in Emacs Lisp if lexical-binding were
set to nil:
(defun map-odd-elements (func list)
(loop for x in list
for flag = t then (not flag)
collect (if flag x (funcall func x))))
(defun add-odd-elements (list x)
(map-odd-elements (lambda (a) (+ a x)) list))
With lexical binding, the two functions’ usages of
x are completely independent. With dynamic
binding, the binding to x made by
add-odd-elements will have been hidden by the
binding in map-odd-elements by the time the
(+ a x) function is called.
Internally, this package uses lexical binding so that such
problems do not occur. See Obsolete
Lexical Binding, for a description of the obsolete
lexical-let form that emulates a Common
Lisp-style lexical binding when dynamic binding is in
use.
', whereas Emacs Lisp’s parser just
treats quote as a special case. Some Lisp packages use reader
macros to create special syntaxes for themselves, which the
Emacs parser is incapable of reading.# that the Emacs Lisp
parser won’t understand. For example, ‘#|
… |#’ is an alternate comment notation, and
‘#+lucid (foo)’ tells the parser to
ignore the (foo) except in Lucid Common Lisp.package:symbol or
package::symbol.
Emacs Lisp has a single namespace for all interned
symbols, and then uses a naming convention of putting a
prefix like cl- in front of the name. Some Emacs
packages adopt the Common Lisp-like convention of using
cl: or cl:: as the prefix. However,
the Emacs parser does not understand colons and just treats
them as part of the symbol name. Thus, while
mapcar and lisp:mapcar may refer to
the same symbol in Common Lisp, they are totally distinct in
Emacs Lisp. Common Lisp programs that refer to a symbol by
the full name sometimes and the short name other times will
not port cleanly to Emacs.
Emacs Lisp does have a concept of “obarrays”, which are package-like collections of symbols, but this feature is not strong enough to be used as a true package mechanism.
format function is quite different between
Common Lisp and Emacs Lisp. It takes an additional
“destination” argument before the format string. A
destination of nil means to format to a string as
in Emacs Lisp; a destination of t means to write
to the terminal (similar to message in Emacs).
Also, format control strings are utterly different;
~ is used instead of % to introduce
format codes, and the set of available codes is much richer.
There are no notations like \n for string
literals; instead, format is used with the
“newline” format code, ~%. More
advanced formatting codes provide such features as paragraph
filling, case conversion, and even loops and conditionals.
While it would have been possible to implement most of
Common Lisp format in this package (under the
name cl-format, of course), it was not deemed
worthwhile. It would have required a huge amount of code to
implement even a decent subset of format, yet
the functionality it would provide over Emacs Lisp’s
format would rarely be useful.
#(a b c) notation in Common Lisp. To further
complicate matters, Emacs has its own #( notation
for something entirely different—strings with
properties.#\A in Common Lisp where Emacs Lisp uses
?A. Also, string= and
string-equal are synonyms in Emacs Lisp, whereas
the latter is case-insensitive in Common Lisp.defconstant where Emacs Lisp uses
defconst. Similarly, make-list takes
its arguments in different ways in the two Lisps but does
exactly the same thing, so this package has not bothered to
implement a Common Lisp-style make-list.compiler-let, prog,
ldb/dpb, cerror.
(defun sum-list (list)
(if list
(+ (car list) (sum-list (cdr list)))
0))
where a more iteratively-minded programmer might write one of these forms:
(let ((total 0)) (dolist (x my-list) (incf total x)) total) (loop for x in my-list sum x)
While this would be mainly a stylistic choice in most Common Lisps, in Emacs Lisp you should be aware that the iterative forms are much faster than recursion. Also, Lisp programmers will want to note that the current Emacs Lisp compiler does not optimize tail recursion.
Next: Obsolete Features, Previous: Common Lisp Compatibility, Up: Top [Contents][Index]